import { makeAutoObservable, observable } from 'mobx';
import * as api from './api';

export default class ScRelevancyStore {
  _args = {
    search: {},
    pg: {
      page: 0,
      sort: ['crDate;desc'],
      size: 10,
    },
  };
  total = 0;
  data = [];
  loading = false;

  fromCities = [];
  toCities = [];
  onStations = [];
  offStations = [];

  citiesMenu = {};
  stationsMenu = {};

  constructor(rootStore) {
    this.rootStore = rootStore;
    makeAutoObservable(this, { rootStore: false });
  }

  get api() {
    return api;
  }

  /**
   * 使用设置的请求参数和分页配置请求列表数据
   * 分页参数为空时保持当前分页配置
   * @param {object} pgInfo 分页参数
   */
  * query(pgInfo) {
    _.mergeWith(this._args.pg, pgInfo, (o, s) => (_.isArray(o) ? s : undefined)); // 数组直接赋值，不合并
    const { search, pg } = toJS(this._args);
    if (!pg.sort?.length) delete pg.sort;
    this.loading = true;
    try {
      this.total = yield api.count({ search });
      const prices = yield api.search({ search, pg });
      this.data = prices;
    } finally {
      this.loading = false;
    }
  }

  * _reload() {
    yield this.query();
  }

  * update(data) {
    yield api.update(data);
    yield this.query();
  }

  * create(data) {
    yield api.create(data);
    yield this.query();
  }

  * get(id) {
    return yield api.get(id);
  }

  * remove(id) {
    yield api.remove(id);
    yield this.query();
  }

  * updateEnable(line) {
    yield api.update({ ...line, enable: !line.enable });
    yield this.query();
  }

  * getFromCity(args) {
    const res = yield api.getCity(args);
    this.fromCities = res.map(({ name, itemId }) => ({ label: name, value: itemId }));
  }

  * getToCity(args) {
    const res = yield api.getCity(args);
    this.toCities = res.map(({ name, itemId }) => ({ label: name, value: itemId }));
  }

  async getScheduleList(args) {
    try {
      const { onCityId, offCityId, onStationId, offStationId } = args || {};
      const res = await api.getPrices({
        priceType: '2',
        startMainArea: onCityId,
        startMinorAreas: [onStationId],
        endMainArea: offCityId,
        endMinorAreas: [offStationId],
      });
      if (res.length === 0) return [];
      const schedule = await api.getShiftsCollectTime({ priceId: res[0].id });
      return schedule;
    } catch (error) {
      console.log('🚀 _ file: ScRelevancyStore.js:99 _ ScRelevancyStore _ error:', error);
      throw error;
    }
  }

  * getOnStations(data) {
    const res = yield api.getStation(data);
    const mergeRes = res.reduce((acc, cur) => {
      return acc.concat(cur.children);
    }, []);
    this.onStations = mergeRes.map(({ name, id }) => ({ label: name, value: id }));
  }

  * getOffStations(data) {
    const res = yield api.getStation(data);
    const mergeRes = res.reduce((acc, cur) => {
      return acc.concat(cur.children);
    }, []);
    this.offStations = mergeRes.map(({ name, id }) => ({ label: name, value: id }));
  }

  * getCitiesStationAllMenu() {
    const cities = yield api.getCity();
    // eslint-disable-next-line @iceworks/best-practices/recommend-polyfill
    const stations = yield Promise.all(cities.map(async (p) => {
      const station = await api.getStation({ direction: '0', fromCities: [p.itemId] });
      const mergeStation = station.reduce((acc, cur) => {
        return acc.concat(cur.children);
      }, []);
      return mergeStation.reduce((acc, cur) => {
        const { id } = cur;
        acc[id] = cur;
        return acc;
      }, {});
    }));
    this.stationsMenu = stations.reduce((acc, cur) => {
      return { ...acc, ...cur };
    }, {});
    this.citiesMenu = cities.reduce((acc, arr) => {
      const { itemId } = arr;
      acc[itemId] = arr;
      return acc;
    }, {});
  }

  idx(i) {
    return this._args.pg.page * this._args.pg.size + i + 1;
  }

  get pg() {
    return this._args.pg;
  }

  set pg(pg) {
    this.query({ ...pg });
    // _.mergeWith(this._args.pg, pg, (o, s) => (_.isArray(o) ? s : undefined)); // 数组直接赋值，不合并
  }

  get search() {
    this._args.pg.page = 0;
    return this._args.search;
  }

  set search(search) {
    this._args.pg.page = 0;
    this._args.search = search;
    this.query({ page: 0 });
  }

  formatArea(stations) {
    const tmp = _.cloneDeep(stations?.selectedPath) || [];
    let res = [];
    if (tmp.length <= 0) return res;
    res = tmp.reduce((result, cur) => {
      result.push(cur.value);
      return result;
    }, []);
    return res;
  }
}
